/** ***********************************************************************************
* @file         net_task.c
* @brief        网络数据处理任务
* @details      主要用来处理基础网络数据
* @author       杨小珛
* @date         2020/12/23
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/

#include "net_task.h"
#include "log_task.h"
#include "net_port.h"
#include "com_lib.h"
#include "mon_task.h"
#include "power_task.h"
/*-------------------------------------------------------------------------
        全局变量定义(Global variable definition)
-----------------------------------------------------------------------*/

#define NET_DATA_NAME "NET_DATA_TASK"
#define NET_RECV_NAME "NET_RECV_TASK"

char *net_socket_recv_taskname[] = { "NET_RECV_TASK1","NET_RECV_TASK2","NET_RECV_TASK3","NET_RECV_TASK4","NET_RECV_TASK5","NET_RECV_TASK6"};

GaozQueueHandle_t net_send_data_queue; /*定义网络发送数据消息队列*/
GaozMutexHandle_t net_link_mutex;       /*定义网络连接互斥体*/
socket_bmt_s socket_bmt;                /*定义网络注册网络句柄*/
net_send_data_s net_send_msg;           /*定位网络数据接收结构体*/
net_rev_data_s net_rev_msg;             /*GPRS接收数据机构体*/
socket_recv_fun_t socket_recv_fun;
socket_state_fun_t socket_state_fun;
static uint8_t net_power_man_id;
static uint32_t ner_reg_error_count;
socket_recv_para_t socket_recv_p[MAX_SOCKET_CONN_NUM];

static void net_send_data_queue_create(void);
static void net_socket_handle_init(void);
static void net_socket_handle_again_init(void);

static void net_data_handle_task( void * pvParameters );
static void net_rece_handle_task( void * pvParameters );

static void net_send_data_queue_init(void);
static uint32_t net_modem_init_work_state(void);
static uint32_t net_modem_core_handshake( void );
static uint32_t net_send_data_processing( uint32_t time_out );
static void net_printf_data_fun(uint8_t mode ,uint8_t * p_data , uint16_t d_len, uint8_t index );
static uint32_t net_recv_data_funtion(uint8_t index , uint8_t * data , uint16_t len );

static socket_status_e net_socket_state_detection( uint8_t index ,char *name,uint8_t *socket_id , uint8_t *buf, uint16_t *len);
static uint32_t net_socket_state_cb( void *state );

static uint32_t net_task_into_run_mode(void);
static uint32_t net_task_into_sleep_mode(void);
static uint32_t net_task_into_stop_mode(void);

static void net_signal_check(void);
static void net_reg_ip_check(void);
static uint32_t net_link_state_check( uint8_t index );
static uint32_t net_wait_net_close_suc(void);
static void net_close_reg_node(network_status_e state);

static void net_send_status_fun( net_send_data_s * data , uint8_t state );
static void net_recv_status_fun( uint8_t index , uint16_t len , uint8_t state );

static void net_reg_error_init(void);
static uint32_t net_reg_error_count(void);
static uint32_t net_reg_state_check( uint8_t index );


/********************************************************************************
重新定义网络功能中使用函数
********************************************************************************/
#define ain_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
#define aisdigit(c) ain_range(c, '0', '9')
#define aisxdigit(c) (aisdigit(c) || ain_range(c, 'a', 'f') || ain_range(c, 'A', 'F'))
#define aislower(c) ain_range(c, 'a', 'z')
#define aisspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')

#define HTONL(x) (x) = htonl((INT32)x)

unsigned long htonl(unsigned long n)
{
    return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
}

unsigned short htons(unsigned short n)
{
    return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
}

int ip4addr_aton(const char *cp, ip4_addr_t *addr)
{
    u32_t val;
    u8_t base;
    char c;
    u32_t parts[4];
    u32_t *pp = parts;

    c = *cp;
    for (;;)
    {
        /*
     * Collect number up to ``.''.
     * Values are specified as for C:
     * 0x=hex, 0=octal, 1-9=decimal.
     */
        if (!aisdigit(c))
        {
            return 0;
        }
        val = 0;
        base = 10;
        if (c == '0')
        {
            c = *++cp;
            if (c == 'x' || c == 'X')
            {
                base = 16;
                c = *++cp;
            }
            else
            {
                base = 8;
            }
        }
        for (;;)
        {
            if (aisdigit(c))
            {
                val = (val * base) + (u32_t)(c - '0');
                c = *++cp;
            }
            else if (base == 16 && aisxdigit(c))
            {
                val = (val << 4) | (u32_t)(c + 10 - (aislower(c) ? 'a' : 'A'));
                c = *++cp;
            }
            else
            {
                break;
            }
        }
        if (c == '.')
        {
            /*
       * Internet format:
       *  a.b.c.d
       *  a.b.c   (with c treated as 16 bits)
       *  a.b (with b treated as 24 bits)
       */
            if (pp >= parts + 3)
            {
                return 0;
            }
            *pp++ = val;
            c = *++cp;
        }
        else
        {
            break;
        }
    }
    /*
   * Check for trailing characters.
   */
    if (c != '\0' && !aisspace(c))
    {
        return 0;
    }
    /*
   * Concoct the address according to
   * the number of parts specified.
   */
    switch (pp - parts + 1)
    {

    case 0:
        return 0; /* initial nondigit */

    case 1: /* a -- 32 bits */
        break;

    case 2: /* a.b -- 8.24 bits */
        if (val > 0xffffffUL)
        {
            return 0;
        }
        if (parts[0] > 0xff)
        {
            return 0;
        }
        val |= parts[0] << 24;
        break;

    case 3: /* a.b.c -- 8.8.16 bits */
        if (val > 0xffff)
        {
            return 0;
        }
        if ((parts[0] > 0xff) || (parts[1] > 0xff))
        {
            return 0;
        }
        val |= (parts[0] << 24) | (parts[1] << 16);
        break;

    case 4: /* a.b.c.d -- 8.8.8.8 bits */
        if (val > 0xff)
        {
            return 0;
        }
        if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
        {
            return 0;
        }
        val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
        break;
    default:
        break;
    }
    if (addr)
    {
        ip4_addr_set_u32(addr, val);
    }
    return 1;
}

/** ****************************************************************************
* @remarks       void net_data_create_task( unsigned portBASE_TYPE uxPriority )
* @brief         创建网络连接处理任务
* @param[in]     uxPriority 优先级
* @param[out]    无
* @return        无
* @attention     在系统启动后进行创建
*******************************************************************************/
void net_data_create_task( unsigned portBASE_TYPE uxPriority )
{   
    net_power_man_id = 0;
    socket_recv_fun = NULL;
    socket_state_fun = NULL;
    net_reg_error_init();
    net_send_data_queue_create(); /* 创建模块网络发送数据的消息队列 */
    net_socket_handle_init(); /*创建网络数据处理句柄*/
    net_link_mutex = gaoz_mutex_create(); /*创建网络连接互斥体*/
    gaoz_thread_create(net_data_handle_task, NET_MAN_NAME, 1024*2*8, NULL, uxPriority);
}
/** ****************************************************************************
* @remarks       static void net_send_data_queue_create(void)
* @brief         创建发送数据消息队列
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_send_data_queue_create(void)
{
    /* 创建模块网络发送数据的消息队列 */
    net_send_data_queue = gaoz_queue_create( NET_SEND_DATA_QUEUE_DEPTH, sizeof( net_send_data_s ) );
    if( net_send_data_queue == 0 )
    {
        while( 1 ); /*创建失败,进行处理*/
    }
}

/** ****************************************************************************
* @remarks       uint32_t net_send_data_queue_get(net_send_data_s *gprs_msg, uint32_t time_out )
* @brief         获取网络数据发送消息队列数据
* @param[in]     *gprs_msg 获取的数据地址
* @param[out]    无
* @return        pdPASS 接收到数据 pdFAIL 未接收到数据
* @attention     必须在任务中运行
*******************************************************************************/
uint32_t net_send_data_queue_get(net_send_data_s *gprs_msg, uint32_t time_out )
{
    if( net_send_data_queue == 0 )
    {
        net_send_data_queue_create();
    }
    if(gaoz_queue_get( net_send_data_queue, gprs_msg, time_out )  == 0 ) //等待回应信号量
    {
        return pdPASS;
    }
    else
    {
        return pdFAIL;
    }
    return pdFAIL;
}
/** ****************************************************************************
* @remarks       static void net_socket_handle_init(void)
* @brief         初始化网络节点数据
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_socket_handle_init(void)
{
    uint16_t i;
    memset((uint8_t *)&socket_bmt , 0x00 , sizeof( socket_bmt_s ) );
    for( i=0 ; i < MAX_SOCKET_CONN_NUM ; i++ )
    {   
        socket_bmt.socket_handle_table[i].connIndex = 0xFF;
        socket_bmt.socket_recv_table[i] = gaoz_queue_create( NET_REV_DATA_QUEUE_DEPTH, sizeof( net_rev_data_s ) );
        if( socket_bmt.socket_recv_table[i] == 0 )
        {
            while( 1 );/*创建失败*/
        }
    }
}

/** ****************************************************************************
* @remarks       static void net_socket_handle_again_init(void)
* @brief         再次清空创建网络节点数据
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_socket_handle_again_init(void)
{
    uint32_t i;
    socket_bmt.socket_create_num = 0;
    for( i=0 ; i < MAX_SOCKET_CONN_NUM ; i++ )
    {   
        memset((uint8_t *)&socket_bmt.socket_handle_table[i] , 0x00 , sizeof( socket_handle_s ));
        socket_bmt.socket_handle_table[i].connIndex = 0xFF;
    }
}
/** ****************************************************************************
* @remarks       static void net_send_data_queue_init(void)
* @brief         网络数据发送消息队列数据清空
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_send_data_queue_init(void)
{
    net_send_data_s send_msg;
    uint32_t i = 0;
    for( i = 0; i < NET_SEND_DATA_QUEUE_DEPTH; i++ )
    {   /*获取数据发送空间中消息队列*/
        if( gaoz_queue_get( net_send_data_queue, &send_msg, 1 )  == 0 )
        {
            if( send_msg.pData != NULL )
            {
                gaoz_free_mem(( void * )send_msg.pData); /*释放内存，检测系统空间尺寸*/
            }
        } 
        else
        {
            break;
        }
    }
}
/** ****************************************************************************
* @remarks       static uint32_t net_modem_core_handshake( void )
* @brief         网络与模块内核进行握手
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static uint32_t net_modem_core_handshake( void )
{
    return net_run_get_at();
}
/** ****************************************************************************
* @remarks       static uint32_t net_modem_init_work_state(void)
* @brief         配置模块所需功能的模块状态
* @param[in]     无
* @param[out]    无
* @return        pdFAIL配置失败  pdPASS配置成功
* @attention     无
*******************************************************************************/
static uint32_t net_modem_init_work_state(void)
{
    if( net_run_get_sim_st() != pdPASS ) return pdFAIL;/*获取SIM卡状态*/
    if( net_run_get_ccid() != pdPASS ) return pdFAIL; /*获取CCID信息*/
    if( net_run_get_imsi() != pdPASS ) return pdFAIL; /*获取模块IMSI信息*/
    if( net_run_get_imei() != pdPASS ) return pdFAIL; /*获取模块IMEI信息*/
    if( net_run_get_csq() != pdPASS ) return pdFAIL; /*获取模块的信号质量*/
    if( net_run_get_reg_info() != pdPASS ) return pdFAIL; /*获取模块模块的注册信息*/
    if( net_run_set_pdp_active( NULL , NULL , NULL ) != pdPASS ) return pdFAIL; /*PDP激活*/
    return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t net_send_data( uint16_t index ,uint8_t * data , uint16_t len )
* @brief         发送GPRS 数据
* @param[in]     index 网络节点
* @param[in]     * data 发送的数据地址
* @param[in]      len 发送的数据长度
* @param[out]    无
* @return        pdFAIL 发送失败 pdPASS 发送成功
* @attention     无
*******************************************************************************/
uint32_t net_send_data( uint16_t index ,uint8_t * data , uint16_t len )
{
    volatile uint32_t  res = pdFAIL;
    volatile uint32_t  osR = 0;
    uint8_t net_st = 0;
    if(data == NULL)
    {
        return pdFAIL;
    }
    if(len > ( NET_SEND_DATA_LEN - 8 ))
    {
        len = (NET_SEND_DATA_LEN -8) ;
    }
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    if( net_st != MODULE_NET_OPEN ) /*获取模块是否处于正常状态*/
    {
        return pdFAIL;  
    }
    /*判断是否注册平台成功*/
    if( socket_bmt.socket_handle_table[index].connStaus != 1 )
    {
        return pdFAIL;
    }
    if( net_link_mutex != 0 )
    {
        gaoz_mutex_lock(net_link_mutex);
        osR = 1;
    }
    net_send_msg.DateLen = len;
    net_send_msg.MsgValidUntil = 0;
    net_send_msg.MsgIndex = index; /*上传socket id*/
    net_send_msg.pData = gaoz_malloc_mem( net_send_msg.DateLen + 8 );
    if( net_send_msg.pData != NULL )
    {
        memcpy(( uint8_t * )&net_send_msg.pData[0],( uint8_t * )data , len );
        if( gaoz_queue_put(net_send_data_queue,&net_send_msg,NET_SEND_QUEUE_BLOCK_TIME) < 0 )
        {
            /*消息发送失败，或者消息队列已满*/
            gaoz_free_mem((void *)net_send_msg.pData);
            log_debug_printf(ERROR_MODE,NET_MAN_NAME ,"[%s]Net send data queue queue is full\r\n",sys_err_infor_pointer_get( 12 ));
            res = pdFAIL;
        }
        else
        {
            res = pdPASS;
        }
    }
    if(osR != 0)
    {
        gaoz_mutex_unlock(net_link_mutex);
    }
    return (res);
}

/** ****************************************************************************
* @remarks       uint32_t net_free_send_data( uint16_t sock_id ,uint8_t * data , uint16_t len )
* @brief         发送GPRS 数据，无节点维护
* @param[in]     sock_id 网络节点
* @param[in]     * data 发送的数据地址
* @param[in]      len 发送的数据长度
* @param[out]    无
* @return        pdFAIL 发送失败 pdPASS 发送成功
* @attention     无
*******************************************************************************/
uint32_t net_free_send_data( uint16_t sock_id ,uint8_t * data , uint16_t len )
{
    volatile uint32_t  res = pdFAIL;
    volatile uint32_t  osR = 0;
    uint8_t net_st = 0;
    if(data == NULL)
    {
        return pdFAIL;
    }
    if(len > ( NET_SEND_DATA_LEN - 8 ))
    {
        len = (NET_SEND_DATA_LEN -8) ;
    }
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    if( net_st != MODULE_NET_OPEN ) /*获取模块是否处于正常状态*/
    {
        return pdFAIL;  
    }
    
    if( net_link_mutex != 0 )
    {
        gaoz_mutex_lock(net_link_mutex);
        osR = 1;
    }
    
    net_printf_data_fun(NET_DATA_SEND ,(uint8_t *)data , len, sock_id );
    if( gaoz_sock_send(sock_id ,(uint8_t *)data ,len ) >= 0 )
    {   
        res = pdPASS;
    }
    
    if(osR != 0)
    {
        gaoz_mutex_unlock(net_link_mutex);
    }
    return (res);
}

/** ****************************************************************************
* @remarks       uint32_t net_connect( char *ip, uint16_t port, uint8_t protocol_type, uint8_t *con_index, uint8_t *conn_staus, uint32_t *con_socketid , uint32_t ip_type)
* @brief         连接GPRS网络
* @param[in]    *ip IP地址 
* @param[in]     port 端口号 
* @param[in]     ip_type 连接类型
* @param[out]    *con_index 连接索引号
* @param[out]    *conn_staus 连接状态
* @param[out]    *con_socketid 网络ID号
* @return        pdFAIL 链接失败 pdPASS 链接成功
* @attention     无
*******************************************************************************/
uint32_t net_connect( char *ip, uint16_t port, uint8_t protocol_type, uint8_t *con_index, uint8_t *conn_staus, uint32_t *con_socketid , uint32_t ip_type)
{
    INT32 socketid = 0 , protocol = 0 ;
    uint8_t net_st = 0 ,index = 0;
    int NODELAY = 1;
    GAPP_TCPIP_ADDR_T addr;
    ip_addr_t addr_dns;
    socket_recv_para_t *recv_p =NULL;
    uint32_t ret = pdFAIL;
    
    *conn_staus = 0x00;
    *con_index = 0x00;
    memset(&addr,0,sizeof(addr));
    memset(&addr_dns,0,sizeof(addr_dns));
    
    if(( ip == NULL )||( port > 65532 ) ||( con_index == NULL ) ||( conn_staus == NULL ))
    {
        return pdFAIL;
    }
    if( strlen((char *)ip) > MAX_IP_LEN ) /*查询网络地址长度是否大于 MAX_IP_LEN */
    {
        return pdFAIL;  
    }
    
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    if( net_st != MODULE_NET_OPEN ) /*获取模块是否处于正常状态*/
    {
        return pdFAIL;  
    }
    
    if( socket_bmt.socket_create_num >= MAX_SOCKET_CONN_NUM )
    {
        return pdFAIL;
    }
    if( protocol_type == e_socket_protocol_tcp )
    {
        protocol = GAPP_IPPROTO_TCP;
    }
    else if( protocol_type == e_socket_protocol_udp )
    {
        protocol = GAPP_IPPROTO_UDP;
    }
    
    socketid = fibo_sock_create(protocol);
    /*判断创建的socketid状态是否正常，同时不能超出最大设定的ID总数*/

    if( socketid < 0 ) 
    {
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Socket creation failed and exits\r\n",0);
        return pdFAIL;
    }
    
    log_debug_printf(DEBUG_MODE,NET_MAN_NAME ,"Socket creation successful,socket id:%d\r\n",socketid );
    if( protocol_type == e_socket_protocol_tcp )
    {
        protocol = IPPROTO_TCP;
    }
    else if( protocol_type == e_socket_protocol_udp )
    {
        protocol = IPPROTO_UDP;
    }
    fibo_sock_setOpt(socketid,protocol,TCP_NODELAY,&NODELAY,sizeof(NODELAY));
    gaoz_task_sleep((UINT32)1000);                   /*系统延时1S中等待系统稳定*/
    addr.sin_port = htons(port);                     /*服务器端口号*/
    if( ip_type == 1 )                               /*CONNECT_TYPE_DOMAIN 域名*/
    {
        fibo_getHostByName(ip,&addr_dns,1,0);
        addr.sin_addr.u_addr.ip4.addr = addr_dns.u_addr.ip4.addr;
    }
    else                                             /*CONNECT_TYPE_IP IP地址*/
    {
        ip4addr_aton(ip, &addr.sin_addr.u_addr.ip4);/*服务器的IP地址*/
        addr.sin_addr.u_addr.ip4.addr = htonl(addr.sin_addr.u_addr.ip4.addr);
    }
    if(fibo_sock_connect(socketid, &addr) < 0)       /*服务器连接成功*/
    {
        fibo_sock_close(socketid);                   /*关闭SOCKID 接口*/
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Network connection failure\r\n",0);
        return pdFAIL;
    }
    log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Network connection successful\r\n",0);
    /************************************设置SOCKET网络参数*******************************************/
    for( index = 0 ; index < MAX_SOCKET_CONN_NUM ; index++ )
    {
        if( socket_bmt.socket_handle_table[index].connStaus == 0 )  /*当前网络未被注册*/
        {
            socket_bmt.socket_create_num ++;
            log_debug_printf(DEBUG_MODE,NET_MAN_NAME ,"Socket creation successful:index=%d,socketid=%d,ip=%s,port=%d\r\n",index ,socketid, ip, port);
            /*handle id*/
            socket_bmt.socket_handle_table[index].connIndex = index;
            socket_bmt.socket_handle_table[index].scoketId = socketid;
            socket_bmt.socket_handle_table[index].protocolType = ( protocol_type_e )protocol_type;
            socket_bmt.socket_handle_table[index].port = port;
            memcpy((uint8_t *)socket_bmt.socket_handle_table[index].ip ,( uint8_t * )ip , strlen( ip ));
            socket_bmt.socket_handle_table[index].connStaus = 1;
            /*初始化回调函数，上层应用不能将回调的值设置为空，因为保存着上层应用的回调指针*/
            socket_bmt.socket_handle_table[index].fDiscCallback = NULL;
            socket_bmt.socket_handle_table[index].sendTotalBytes = 0x00;
            socket_bmt.socket_handle_table[index].recvTotalBytes = 0x00;

            break;
        }
    }
    /*创建 网络数据接收任务*/
    if( index < MAX_SOCKET_CONN_NUM )
    {
        *con_index = index;
        *conn_staus = 0x01;
        *con_socketid = socketid;
        /******************************************************************/
        recv_p = &socket_recv_p[index];
        recv_p->index = index;
        recv_p->buf = ( uint8_t * )gaoz_fibo_malloc( NET_RECV_DATA_LEN );
        recv_p->name = net_socket_recv_taskname[index];
        if( recv_p->buf != NULL )
        {
            if( gaoz_thread_create( net_rece_handle_task, net_socket_recv_taskname[index], 1024*2*8, recv_p, OSI_PRIORITY_NORMAL ) == 0 )
            {
                ret = pdPASS;
                log_debug_send( DEBUG_MODE,NET_MAN_NAME ,"Network data receive task creation successful\r\n",0 );
            }
            else
            {
                ret = pdFAIL;
                gaoz_fibo_free( ( void * )recv_p->buf );
                log_debug_send( DEBUG_MODE,NET_MAN_NAME ,"Network data receive task creation failed\r\n",0 );
            }
        }
    }
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t net_free_connect( char *ip, uint16_t port, uint8_t protocol_type, uint8_t *con_index, uint8_t *conn_staus, uint32_t *con_socketid , uint32_t ip_type)
* @brief         连接GPRS网络，无节点维护
* @param[in]    *ip IP地址 
* @param[in]     port 端口号 
* @param[in]     ip_type 连接类型
* @param[out]    *con_socketid 网络ID号
* @return        pdFAIL 链接失败 pdPASS 链接成功
* @attention     无
*******************************************************************************/
uint32_t net_free_connect( char *ip, uint16_t port, uint8_t protocol_type, uint32_t *con_socketid , uint32_t ip_type)
{
    INT32 socketid = 0 , protocol = 0 ;
    uint8_t net_st = 0;
    int NODELAY = 1;
    GAPP_TCPIP_ADDR_T addr;
    ip_addr_t addr_dns;
    uint32_t  osR = 0;
    
    memset(&addr,0,sizeof(addr));
    memset(&addr_dns,0,sizeof(addr_dns));
    
    if(( ip == NULL )||( port > 65532 ) )
    {
        return pdFAIL;
    }
    if( strlen((char *)ip) > MAX_IP_LEN ) /*查询网络地址长度是否大于 MAX_IP_LEN */
    {
        return pdFAIL;  
    }
    
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    if( net_st != MODULE_NET_OPEN ) /*获取模块是否处于正常状态*/
    {
        return pdFAIL;  
    }
    
    if( net_link_mutex != 0 )
    {
        gaoz_mutex_lock(net_link_mutex);
        osR = 1;
    }
    
    if( protocol_type == e_socket_protocol_tcp )
    {
        protocol = GAPP_IPPROTO_TCP;
    }
    else if( protocol_type == e_socket_protocol_udp )
    {
        protocol = GAPP_IPPROTO_UDP;
    }
    
    socketid = fibo_sock_create(protocol);
    /*判断创建的socketid状态是否正常，同时不能超出最大设定的ID总数*/

    if( socketid < 0 ) 
    {
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Socket creation failed and exits\r\n",0);
        return pdFAIL;
    }
    
    log_debug_printf(DEBUG_MODE,NET_MAN_NAME ,"Socket creation successful,socket id:%d\r\n",socketid );
    if( protocol_type == e_socket_protocol_tcp )
    {
        protocol = IPPROTO_TCP;
    }
    else if( protocol_type == e_socket_protocol_udp )
    {
        protocol = IPPROTO_UDP;
    }
    fibo_sock_setOpt(socketid,protocol,TCP_NODELAY,&NODELAY,sizeof(NODELAY));
    gaoz_task_sleep((UINT32)1000);                   /*系统延时1S中等待系统稳定*/
    addr.sin_port = htons(port);                     /*服务器端口号*/
    if( ip_type == 1 )                               /*CONNECT_TYPE_DOMAIN 域名*/
    {
        fibo_getHostByName(ip,&addr_dns,1,0);
        addr.sin_addr.u_addr.ip4.addr = addr_dns.u_addr.ip4.addr;
    }
    else                                             /*CONNECT_TYPE_IP IP地址*/
    {
        ip4addr_aton(ip, &addr.sin_addr.u_addr.ip4);/*服务器的IP地址*/
        addr.sin_addr.u_addr.ip4.addr = htonl(addr.sin_addr.u_addr.ip4.addr);
    }
    if(fibo_sock_connect(socketid, &addr) < 0)       /*服务器连接成功*/
    {
        fibo_sock_close(socketid);                   /*关闭SOCKID 接口*/
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Network connection failure\r\n",0);
        return pdFAIL;
    }
    log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Network connection successful\r\n",0);
    /************************************设置SOCKET网络参数*******************************************/
    *con_socketid = socketid;
    
    if(osR != 0)
    {
        gaoz_mutex_unlock(net_link_mutex);
    }
    
    return pdPASS;
}

/** ****************************************************************************
* @remarks       int32_t  net_free_recv( uint16_t sock_id ,uint8_t * data , uint16_t len )
* @brief         接收 TCP 数据函数，一次读取最长不超过 2048 字节。
* @param[in]     sock 创建的sock id  
* @param[in]     len 接收数据 data 首地址 
* @param[out]    *data 数据首地址
* @return        ≥0 - 实际接收到的数据长度(对端正常断开为 0) ＜0 - socket 错误（网络异常断开-1）
* @attention     无
*******************************************************************************/
int32_t net_free_recv( uint16_t sock_id ,uint8_t * data , uint16_t len )
{       
    int32_t ret = -1;
    if((data == NULL) || ( len > NET_RECV_DATA_LEN ))
    {
        return ret;
    }
    ret = gaoz_sock_recv( sock_id, data, len );
    if( ret > 0 )
    {
        net_printf_data_fun(NET_DATA_RECV ,(uint8_t *)data , ret, sock_id );
    }
    return ret;
}
/** ****************************************************************************
* @remarks       uint32_t net_close(uint16_t index ,uint8_t type)
* @brief         关闭NET 网络链接
* @param[in]     index 网络节点
* @param[in]     type 网络连接模式
* @param[out]    无
* @return        pdFAIL 发送失败 pdPASS 发送成功
* @attention     无
*******************************************************************************/
uint32_t net_close(uint16_t index ,uint8_t type)
{
    uint32_t ret = 0;
        
    if( type == e_socket_protocol_tcp )
    {
        
    }
    else if( type == e_socket_protocol_udp )
    {
        
    }
    
    if( fibo_sock_close( index ) < 0 )
    {
        log_debug_printf(INFOR_MODE,NET_MAN_NAME ,"Socket closed failed,Socket ID=%d\r\n",index);
        ret = pdFAIL;
    }
    else
    {
        log_debug_printf(INFOR_MODE,NET_MAN_NAME ,"Socket closed successfully,Socket ID=%d\r\n",index);
        ret = pdPASS;
    }
    return ret;
}

/** ****************************************************************************
* @remarks       void net_socket_state_callback_set( socket_handle_s *pxSocketHandle )
* @brief         设置网络状态回调函数
* @param[in]     *pxSocketHandle 网络套接字
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void net_socket_state_callback_set( socket_handle_s *pxSocketHandle )
{
    if( pxSocketHandle == NULL )
        return;
    if( pxSocketHandle->connIndex >= MAX_SOCKET_CONN_NUM )
        return;
    socket_bmt.socket_handle_table[pxSocketHandle->connIndex].fDiscCallback = pxSocketHandle->fDiscCallback;
}

/** ****************************************************************************
* @remarks       void net_recv_data_callback_set( socket_recv_fun_t  fun )
* @brief         设置网络数据接收回调函数
* @param[in]     fun API 函数地址
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void net_recv_data_callback_set( socket_recv_fun_t  fun )
{
    if( socket_recv_fun == NULL )
    {
        socket_recv_fun = fun;
    }
}

/** ****************************************************************************
* @remarks       void socket_net_state_callback_set( socket_state_fun_t  fun )
* @brief         设置网络状态回调函数
* @param[in]     fun API 函数地址
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void socket_net_state_callback_set( socket_state_fun_t  fun )
{
    if( socket_state_fun == NULL )
    {
        socket_state_fun = fun;
    }
}

/** ****************************************************************************
* @remarks       uint32_t net_send_data_total_count_get( void )
* @brief         获取网络发送数据的总量
* @param[in]     index 网络节点
* @param[out]    无
* @return        网络发送数据包总个数，单位 byte
* @attention     无
*******************************************************************************/
uint32_t net_send_data_total_count_get( uint8_t index )
{
    if( index >= MAX_SOCKET_CONN_NUM )
    {
        return 0;
    }
    return socket_bmt.socket_handle_table[index].sendTotalBytes;
}

/** ****************************************************************************
* @remarks       uint32_t net_recv_data_total_count_get( void )
* @brief         获取网络接收数据的总量
* @param[in]     index 网络节点 
* @param[out]    无
* @return        网络接收数据包总个数，单位 byte
* @attention     无
*******************************************************************************/
uint32_t net_recv_data_total_count_get( uint8_t index )
{
    if( index >= MAX_SOCKET_CONN_NUM )
    {
        return 0;
    }
    return socket_bmt.socket_handle_table[index].recvTotalBytes;;
}

/** ****************************************************************************
* @remarks       uint32_t net_connection_status_get( uint8_t index )
* @brief         获取网络的连接状态
* @param[in]     index 网络节点
* @param[out]    无
* @return        pdPASS 网络连接成功，pdFAIL 网络连接失败
* @attention     无
*******************************************************************************/
uint32_t net_connection_status_get( uint8_t index )
{
    uint32_t ret = pdFAIL;

    if( index >= MAX_SOCKET_CONN_NUM )
    {
        return pdFAIL;
    }
    if( socket_bmt.socket_handle_table[index].connStaus == 1 )
    {
        ret = pdPASS;
    }

    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t net_dns_ip_addr_get( char *dns, char *get_ip )
* @brief         获取域名IP地址
* @param[in]     *dns 域名地址
* @param[out]    *get_ip 解析后的IP地址
* @return        pdFAIL 失败，pdPASS 成功
* @attention     无
*******************************************************************************/
uint32_t net_dns_ip_addr_get( char *dns, char *get_ip )
{
    uint32_t ret = pdFAIL;
    ip_addr_t addr_dns;
    uint8_t addr_ip[4] = { 0 };
    uint8_t net_st = 0;

    if(( dns == NULL ) || ( get_ip == NULL ))
    {
        return pdFAIL;
    }
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    if( net_st != MODULE_NET_OPEN ) /*获取模块是否处于正常状态*/
    {
        return pdFAIL;  
    }
    if( fibo_getHostByName(dns,&addr_dns,1,0) == 0 )
    {
        addr_ip[3] = (uint8_t)( addr_dns.u_addr.ip4.addr & 0x000000FF );
        addr_ip[2] = (uint8_t)(( addr_dns.u_addr.ip4.addr & 0x0000FF00 ) >> 8 );
        addr_ip[1] = (uint8_t)(( addr_dns.u_addr.ip4.addr & 0x00FF0000 ) >> 16 );
        addr_ip[0] = (uint8_t)(( addr_dns.u_addr.ip4.addr & 0xFF000000 ) >> 24 );
        sprintf(get_ip, "%d.%d.%d.%d", addr_ip[3], addr_ip[2], addr_ip[1], addr_ip[0]);
        ret = pdPASS;
    }

    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_recv_data_funtion(uint8_t index , uint8_t * data , uint16_t len )
* @brief         回调上层函数，发送接收到的数据
* @param[in]     index 网络索引号
* @param[in]     * data 收到数据的头地址
* @param[in]     len 收到数据的长度
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static uint32_t net_recv_data_funtion(uint8_t index , uint8_t * data , uint16_t len )
{
    if( socket_recv_fun == NULL )
        return pdFAIL;
    return socket_recv_fun(index,data,len);
}

/** ****************************************************************************
* @remarks       static uint32_t net_socket_state_cb( void * state )
* @brief         socket 网络状态 ，回调函数
* @param[in]     *state 发送的数据不定类型
* @param[out]    无
* @return        pdPASS 发送数据成功  pdFAIL 发送数据失败
* @attention     无
*******************************************************************************/
static uint32_t net_socket_state_cb( void *state )
{
	if( socket_state_fun == NULL )
    {
		return pdFAIL;
    }
	socket_state_fun(state);
	return pdPASS;
}

/** ****************************************************************************
* @remarks       static void net_printf_data_fun(uint8_t mode ,uint8_t * p_data , uint16_t d_len, uint8_t index )
* @brief         打印网络数据
* @param[in]     mode 打印模式 NET_DATA_RECV 接收数据  NET_DATA_SEND 发送数据
* @param[in]     * p_data 数据的源地址
* @param[in]     d_len 数据的长度
* @param[in]     index 网络节点
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_printf_data_fun(uint8_t mode ,uint8_t * p_data , uint16_t d_len, uint8_t index )
{
    #define NET_UART_TX_QUEUE_LEN   ( 512 )    //DEBUG_UART_TX_QUEUE_LEN
    uint8_t *pBuf = NULL , i = 0;
    uint16_t data_len = 0 ,print = 0;
    char *task_name = NULL;
    
    if( mode == NET_DATA_RECV )
    {
        if( d_len > NET_RECV_DATA_LEN ) 
        {
            return;
        }
    }
    else
    {
        if( d_len > NET_SEND_DATA_LEN ) 
        {
            return;
        }
    }
    /*动态申请空间，由于接收的数据需要转变为STRING类型，数据量是原始数据的2倍*/
    pBuf = gaoz_malloc_mem( d_len * 2  + 100 );
    if( pBuf != NULL )
    {
        if( mode == NET_DATA_RECV )
        {
            task_name = NET_RECV_NAME;
            data_len = sprintf((char *)pBuf,"Socket network receiving data:%d,%d,",index , d_len);
        }
        else /*NET_DATA_SEND*/
        {
            task_name = NET_MAN_NAME;
            data_len = sprintf((char *)pBuf,"Socket network transmit data:%d,%d,",index , d_len);
        }
        data_len += HexToAsciiString((char *)&pBuf[data_len],( const char * )p_data, d_len);
        pBuf[ data_len ] = '\r';
        data_len++;
        pBuf[ data_len ] = '\n';
        data_len++;
        /*发送数据*/
        print = data_len / NET_UART_TX_QUEUE_LEN;
        for( i = 0 ; i < print ; i ++ )
        {
            log_debug_send(INFOR_MODE,task_name ,&pBuf[i*NET_UART_TX_QUEUE_LEN],NET_UART_TX_QUEUE_LEN);
        }
        print = data_len % NET_UART_TX_QUEUE_LEN;
        if( print != 0 )
        {
            log_debug_send(INFOR_MODE,task_name ,&pBuf[i*NET_UART_TX_QUEUE_LEN],print);
        }
        gaoz_free_mem( (void *)pBuf );
    }
}

/** ****************************************************************************
* @remarks       static void net_signal_check(void)
* @brief         检测模组的信号质量，通知上层应用
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_signal_check(void)
{
	uint8_t i = 0 , signal = 0;
	socket_net_state_s sig_state;
	
	for( i = 0 ; i < MAX_SOCKET_CONN_NUM ; i++ ) 
	{
		if( socket_bmt.socket_handle_table[i].connIndex != 0xFF ) 
		{	
			sig_state.net_state = SOCKET_CSQ_ERROR;
			sig_state.index_id = i;
            net_module_run_state_get( NET_SIGNAL , ( void *)&signal );
			sig_state.attr_data = signal;
			net_socket_state_cb( ( void * )&sig_state );
		}
	}
}

/** ****************************************************************************
* @remarks       static void net_reg_ip_check(void)
* @brief         检测注册物理层网络连接状态
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_reg_ip_check(void)
{
	uint8_t i = 0;
	socket_net_state_s ip_state;
	for( i = 0 ; i < MAX_SOCKET_CONN_NUM ; i++ )
	{
		if( socket_bmt.socket_handle_table[i].connIndex != 0xFF )
		{	
			ip_state.net_state = SOCKET_REG_ERROR;
			ip_state.index_id = i;
			ip_state.attr_data = 0;
            net_socket_state_cb( ( void * )&ip_state ); /* 通知上层应用 物理层网络连接失败*/
		}
	}
}

/** ****************************************************************************
* @remarks       static void net_link_state_check( uint8_t index )
* @brief         检测网络服务器连接的状态
* @param[in]     index 网络连接的节点
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static uint32_t net_link_state_check( uint8_t index )
{
    uint32_t ret = pdFAIL;
	socket_net_state_s link_state;
    if(( socket_bmt.socket_handle_table[index].connIndex != 0xFF ) && ( socket_bmt.socket_handle_table[index].connStaus == 1 ))
    {
        link_state.net_state = SOCKET_LINK_ERROR;
        link_state.index_id = index;
        link_state.attr_data = 0;
        net_socket_state_cb( ( void * )&link_state ); 
        ret = pdPASS;
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static void net_reg_state_check( uint8_t index )
* @brief         检测终端和网络连接的状态
* @param[in]     index 网络连接的节点
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static uint32_t net_reg_state_check( uint8_t index )
{
    uint32_t ret = pdFAIL;
	socket_net_state_s link_state;
    if(( socket_bmt.socket_handle_table[index].connIndex != 0xFF ) && ( socket_bmt.socket_handle_table[index].connStaus == 1 ))
    {	
        link_state.net_state = SOCKET_REG_ERROR;
        link_state.index_id = index;
        link_state.attr_data = 0;
        net_socket_state_cb( ( void * )&link_state ); 
        ret = pdPASS;
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_wait_net_close_suc(void)
* @brief         等待注册成功的网络节点关闭成功
* @param[in]     无
* @param[out]    无
* @return        pdPASS 关闭成功 pdFAIL 关闭失败
* @attention     无
*******************************************************************************/
static uint32_t net_wait_net_close_suc(void)
{
	uint8_t index = 0;
	uint16_t ret = pdFAIL;
	uint16_t i = 0 ;
	
	for( i = 0 ; i < MAX_SOCKET_CONN_NUM ; i++ )
	{
		if(( socket_bmt.socket_handle_table[i].connIndex == 0xFF ) && ( socket_bmt.socket_handle_table[i].connStaus == 0x00 ))
		{	
			index ++;
		}
	}
	if( index  >=  MAX_SOCKET_CONN_NUM ) 
	{
		ret = pdPASS;
	}
	
	return ( ret );
}

/** ****************************************************************************
* @remarks       static void net_close_reg_node(network_status_e state)
* @brief         关闭注册的网络节点
* @param[in]     state 发送网络的状态
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_close_reg_node(network_status_e state)
{
	uint8_t i = 0;
	socket_net_state_s reg_state;
	
	for( i = 0 ; i < MAX_SOCKET_CONN_NUM ; i++ )
	{
        if(( socket_bmt.socket_handle_table[i].connIndex != 0xFF ) && ( socket_bmt.socket_handle_table[i].connStaus == 1 ))
		{
			reg_state.net_state = state;
			reg_state.index_id = i;
			reg_state.attr_data = 0;
			net_socket_state_cb( ( void * )&reg_state );	
		}
	}
}

/** ****************************************************************************
* @remarks       static void net_send_status_fun( net_send_data_s * data , uint8_t state )
* @brief         
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_send_status_fun( net_send_data_s * data , uint8_t state )
{
	socket_net_state_s socket_send_state;
	if(( data->MsgIndex >= MAX_SOCKET_CONN_NUM ) || ( data == NULL ))
		return;
	if( state == NET_DATA_SEND_OK )
	{
		socket_bmt.socket_handle_table[data->MsgIndex].sendTotalBytes += data->DateLen;
		socket_send_state.net_state = SOCKET_SEND_OK;
		socket_send_state.index_id = data->MsgIndex;
		socket_send_state.attr_data = socket_bmt.socket_handle_table[data->MsgIndex].sendTotalBytes;
	}
	else
	{
		socket_bmt.socket_handle_table[data->MsgIndex].sendTotalBytes += 0;
		socket_send_state.net_state = SOCKET_SEND_ERROR;
		socket_send_state.index_id = data->MsgIndex;
		socket_send_state.attr_data = 0;
	}
	net_socket_state_cb( ( void * )&socket_send_state ); 	
}

/** ****************************************************************************
* @remarks       static void net_recv_status_fun( uint8_t index , uint16_t len , uint8_t state )
* @brief         检测注册物理层网络连接状态
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_recv_status_fun( uint8_t index , uint16_t len , uint8_t state )
{
	socket_net_state_s socket_recv_state;
	if( index >= MAX_SOCKET_CONN_NUM ) 
		return;
	if( state == NET_DATA_RECV_OK )
	{
		socket_bmt.socket_handle_table[index].recvTotalBytes += len;
		socket_recv_state.net_state = SOCKET_RECV_OK;
		socket_recv_state.index_id = index;
		socket_recv_state.attr_data = socket_bmt.socket_handle_table[index].sendTotalBytes;
	}
	else
	{
		socket_bmt.socket_handle_table[index].recvTotalBytes += 0;
		socket_recv_state.net_state = SOCKET_RECV_ERROR;
		socket_recv_state.index_id = index;
		socket_recv_state.attr_data = 0;
	}
	net_socket_state_cb( ( void * )&socket_recv_state ); 	
}

/** ****************************************************************************
* @remarks       static void net_reg_error_init(void)
* @brief         网络注册异常计数器 初始化
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_reg_error_init(void)
{
	ner_reg_error_count = 0;
}
/** ****************************************************************************
* @remarks       static uint32_t net_reg_error_count(void)
* @brief         网络注册异常计数器
* @param[in]     无
* @param[out]    无
* @return        pdTRUE 计数时间到 ， pdFALSE 计数时间位到
* @attention     无
*******************************************************************************/
static uint32_t net_reg_error_count(void)
{
	uint32_t ret = pdFAIL;
	ner_reg_error_count++;
	if( ner_reg_error_count > NER_REG_ERROR_TIME_OUT )
	{	
	    ner_reg_error_count = NER_REG_ERROR_TIME_OUT; /*赋值，保持溢出状态*/
		ret = pdPASS;
	}
	return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_send_data_processing( uint32_t time_out )
* @brief         获取发送的网络数据
* @param[in]     无
* @param[out]    无
* @return        pdTRUE 数据发送成功 ， pdFALSE 数据发送失败
* @attention     无
*******************************************************************************/
static uint32_t net_send_data_processing( uint32_t time_out )
{
    uint32_t ret = SEND_NET_INIT;
    net_send_data_s send_data;
    uint8_t net_st = 0;
    uint8_t net_signal = 0;
    uint32_t sock_id = 0;
    if( time_out == NET_SEND_DATA_RUN_WAIT_TIME )
    {
        if( net_send_data_queue_get( &send_data , time_out ) == pdPASS )
        {
            net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
            if( net_st == MODULE_NET_OPEN )                         /*网络运行状态正常*/
            {
                sock_id = socket_bmt.socket_handle_table[send_data.MsgIndex].scoketId;
                net_printf_data_fun(NET_DATA_SEND ,(uint8_t *)send_data.pData , send_data.DateLen, sock_id );
                if( gaoz_sock_send(sock_id ,(uint8_t *)send_data.pData ,send_data.DateLen ) >= 0 )
                {   
                    net_send_status_fun( (net_send_data_s * )&send_data , NET_DATA_SEND_OK );     /*数据发送成功*/
                }
                else
                {
                    net_send_status_fun( (net_send_data_s * )&send_data , NET_DATA_SEND_ERROR );  /*数据发送失败*/
                }
            }
            gaoz_free_mem(( void * )send_data.pData);               /*数据发送完毕后清空内存*/
            ret = SEND_NET_OK;
        }
        else
        {   
            net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
            if( net_st == MODULE_NET_OPEN )
            {
                log_debug_printf(INFOR_MODE,NET_MAN_NAME ,"net_st == MODULE_NET_OPEN\r\n",0);
                if( net_run_check_reg_status() == pdPASS )          /*检测终端是否附着到网络*/
                {
                    net_st = MODULE_NET_OPEN;                       /*网络正常*/
                    net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                }
                else
                {
                    net_st = MODULE_NET_ERR;                        /*网络异常*/
                    net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                }
                net_reg_error_init();
            }
            else
            {   
                if( net_run_check_sim_status() == pdPASS )          /*检测SIM卡状态正常，断网为其他原因*/
                {
                    log_debug_printf(INFOR_MODE,NET_MAN_NAME ,"net_st != MODULE_NET_OPEN SIM INSERT  ner_reg_error_count= %d/%d\r\n",ner_reg_error_count,NER_REG_ERROR_TIME_OUT);
                    if( net_reg_error_count() == pdPASS )           /*网络注册失败后等待大约10分钟的时间，然后重新对L610进行复位操作*/
                    {
                        net_close_reg_node( GSM_NET_RST );          
                        net_st = MODULE_NET_RST;                    /*标记网络需要重新进行复位操作*/
                        net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                        ret = SEND_NET_ERR;
                    }
                    else
                    {
                        net_run_net_release();                      /*当网络异常时，首先对网络进行去激活操作。*/                    
                        if( net_run_reset_net_init() == pdPASS )  
                        {
                            net_st = MODULE_NET_OPEN;                /*标记网络处于异常状态*/
                            net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                        }
                        else
                        {
                            net_reg_ip_check();                      /*检测物理层网络连接状态，当不满足是通知上层应用*/
                        }
                        /***************************************获取终端的信号质量*************************/
                        net_module_run_state_set( NET_SIGNAL ,(uint8_t *)&net_signal );
                        if( net_signal == 0 )                       
                        {
                            net_signal_check();                      /*判断信号质量是否异常，异常后通知应用*/
                        }
                    }
                }
                else                                                 /*检测到外部SIM卡断开，重新启动模块*/ 
                {   
                    if( net_run_reset_net_init() == pdPASS )      
                    {
                        net_st = MODULE_NET_OPEN;                    /*标记网络处于异常状态*/
                        net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                    }
                    else
                    {
                        log_debug_printf(INFOR_MODE,NET_MAN_NAME ,"net_st != MODULE_NET_OPEN SIM NOT INSERT  ner_reg_error_count= %d/%d\r\n",ner_reg_error_count,NER_REG_ERROR_TIME_OUT);
                   
                        if( net_reg_error_count() == pdPASS )       
                        {
                            net_close_reg_node( GSM_NET_RST );      /*检测物理层网络连接状态，当不满足是通知上层应用*/
                            net_st = MODULE_NET_RST;                /*标记网络需要重新进行复位操作*/
                            net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                            ret = SEND_NET_ERR;
                        }
                        else
                        {
                            net_st = MODULE_NET_ERR;                /*网络异常*/
                            net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_st );
                        }
                    }
                }
            }
        }
    }
    else
    {
        if( net_send_data_queue_get( &send_data , time_out ) == pdPASS )
        {
            net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
            if( net_st == MODULE_NET_OPEN )                         /*网络运行状态正常*/
            {
                sock_id = socket_bmt.socket_handle_table[send_data.MsgIndex].scoketId;
                net_printf_data_fun(NET_DATA_SEND ,(uint8_t *)send_data.pData , send_data.DateLen, sock_id );
                if( gaoz_sock_send(sock_id ,(uint8_t *)send_data.pData ,send_data.DateLen ) >= 0 )
                {   
                    net_send_status_fun( (net_send_data_s * )&send_data , NET_DATA_SEND_OK );     /*数据发送成功*/
                }
                else
                {
                    net_send_status_fun( (net_send_data_s * )&send_data , NET_DATA_SEND_ERROR );  /*数据发送失败*/
                }
            }
            gaoz_free_mem(( void * )send_data.pData);               /*数据发送完毕后清空内存*/
            ret = SEND_NET_OK;
        }
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_task_into_run_mode(void)
* @brief         net任务进入运行状态
* @param[in]     无
* @param[out]    无
* @return        pdPASS 设置成功 pdFAIL 设置失败
* @attention     无
*******************************************************************************/
static uint32_t net_task_into_run_mode(void)
{
    task_modules_e state = TASK_MODE_INIT;
    uint32_t ret = pdFAIL; 
    state = power_man_save_state_get( net_power_man_id ); /*获取任务的运行状态*/
    if( state != TASK_RUN_MODE )
    {   
        power_man_save_state_set( net_power_man_id ,TASK_RUN_MODE );
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"<<<<<<<<<<*****NET task enters RUN mode*****>>>>>>>>>>\r\n", 0);
        ret = pdPASS; 
    }
    else if( state == TASK_RUN_MODE )
    {
        ret = pdPASS; 
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_task_into_sleep_mode(void)
* @brief         net任务进入睡眠状态
* @param[in]     无
* @param[out]    无
* @return        pdPASS 设置成功 pdFAIL 设置失败
* @attention     无
*******************************************************************************/
static uint32_t net_task_into_sleep_mode(void)
{
    task_modules_e state = TASK_MODE_INIT;
    uint32_t ret = pdFAIL; 
    state = power_man_save_state_get( net_power_man_id ); /*获取任务的运行状态*/
    if( state != TASK_SLEEP_MODE )
    {   
        power_man_save_state_set( net_power_man_id ,TASK_SLEEP_MODE );
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"<<<<<<<<<<*****NET task enters SLEEP mode*****>>>>>>>>>>\r\n", 0);
        ret = pdPASS; 
    }
    else if( state == TASK_SLEEP_MODE )
    {
        ret = pdPASS; 
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static uint32_t net_task_into_stop_mode(void)
* @brief         net任务进入停止状态
* @param[in]     无
* @param[out]    无
* @return        pdPASS 设置成功 pdFAIL 设置失败
* @attention     无
*******************************************************************************/
static uint32_t net_task_into_stop_mode(void)
{
    task_modules_e state = TASK_MODE_INIT;
    uint32_t ret = pdFAIL; 
    state = power_man_save_state_get( net_power_man_id ); /*获取任务的运行状态*/
    if( state != TASK_STOP_MODE )
    {   
        power_man_save_state_set( net_power_man_id ,TASK_STOP_MODE );
        log_debug_send(INFOR_MODE,NET_MAN_NAME ,"<<<<<<<<<<*****NET task enters STOP mode*****>>>>>>>>>>\r\n", 0);
        ret = pdPASS; 
    }
    else if( state == TASK_STOP_MODE )
    {
        ret = pdPASS; 
    }
    return ret;
}

/** ****************************************************************************
* @remarks       static void net_data_handle_task( void * pvParameters )
* @brief         处理网络基层数据处理任务
* @param[in]     * pvParameters 任务参数
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_data_handle_task( void * pvParameters )
{
    ( void ) pvParameters;
    volatile uint8_t net_run_st = 0;    /*网络运行参数设置*/
    volatile uint32_t net_send_st = 0;
    volatile uint32_t net_sleep_time = 0;
    task_modules_e net_power_st = TASK_MODE_INIT;
    mon_reg_task_dog( 60 * GAOZ_TICK_PERIOD_S ,(uint8_t * )NET_MAN_NAME , TASK_SEM_YES );
    power_man_task_reg((uint8_t * )NET_MAN_NAME,(uint8_t *)&net_power_man_id );         /*注册系统电源管理*/
    log_debug_send(DEBUG_MODE,NET_MAN_NAME ,"Network data management task started successfully\r\n",0);
    for( ;; ) 
    {
        mon_reset_task_dog();
        net_power_st = power_man_task_state_get( net_power_man_id );                    /*获取任务运行的状态*/
        if(( net_power_st == TASK_MODE_INIT ) || ( net_power_st == TASK_RUN_MODE ))
        {
            net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_run_st );
            if( net_run_st == MODULE_NET_RST )
            {
                log_debug_send( INFOR_MODE,NET_MAN_NAME ,"Network reset\r\n",0 );
                gaoz_cfun_zero();
            }
            gaoz_task_sleep(5000);                                                      /*延时5S等待网络系统稳定*/
            gaoz_cfun_one();
            net_run_port_par_init(); 
            net_send_data_queue_init();
            net_socket_handle_again_init();
            if( net_modem_core_handshake() != pdPASS )                                  /*与L610网络内核进行握手*/
            {
                log_debug_send( INFOR_MODE,NET_MAN_NAME ,"Network kernel handshake failed\r\n",0 );
                net_run_st = MODULE_NET_ERR;
                net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_run_st );
                power_man_save_state_set( net_power_man_id ,TASK_RUN_MODE );
                continue;
            }
            else
            {
                log_debug_send(INFOR_MODE,NET_MAN_NAME ,"Started to register for the network\r\n",0);
                if( net_modem_init_work_state() != pdPASS )                             /*初始化模块运行状态*/
                {   
                    net_run_st = MODULE_NET_RST;
                    net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_run_st );      /*初始化系统模块失败，重新启动*/
                    power_man_save_state_set( net_power_man_id ,TASK_RUN_MODE );
                    continue;
                }
                else
                {
                    net_run_st = MODULE_NET_OPEN;
                    net_module_run_state_set( MOD_STATE ,(uint8_t *)&net_run_st );     /*网络可以正常使用*/
                    log_debug_send( INFOR_MODE,NET_MAN_NAME ,"Network registration successful\r\n",0 );
                }
            }   
        }
        else if( net_power_st == TASK_SLEEP_MODE )
        {
            power_man_save_state_set( net_power_man_id ,TASK_SLEEP_MODE );
            fibo_taskSleep( 1000 ); 
            continue;
        }
        else if( net_power_st == TASK_STOP_MODE )
        {
            power_man_save_state_set( net_power_man_id ,TASK_STOP_MODE );
            fibo_taskSleep( 1000 ); 
            continue;
        }
        power_man_save_state_set( net_power_man_id ,TASK_MODE_INIT );
        for( ;; )
        {
            mon_reset_task_dog();
            net_power_st = power_man_task_state_get( net_power_man_id );           /*获取任务运行的状态*/
            /*******************************NET任务处于运行状态************************************/
            if( net_power_st == TASK_RUN_MODE )
            {
                if( net_task_into_run_mode() !=  pdPASS )
                {
                    gaoz_task_sleep(1000);
                    continue;
                }
                net_sleep_time = 0;
                net_close_reg_node( GSM_NET_RUN );                                 /*模块处于运行模式*/
                if( net_send_data_processing( NET_SEND_DATA_RUN_WAIT_TIME ) == SEND_NET_ERR )
                {
                    break;
                }
            }
            /*******************************NET任务处于休眠状态************************************/
            else if( net_power_st == TASK_SLEEP_MODE )
            {
                net_send_st = net_send_data_processing( NET_SEND_DATA_STOP_WAIT_TIME );
                if( net_send_st == SEND_NET_INIT )
                {
                    net_sleep_time ++;
                    if( net_sleep_time >= POWER_MAN_TASK_INTO_SLEPP_TIME )
                    {
                        net_sleep_time = POWER_MAN_TASK_INTO_SLEPP_TIME;
                        net_close_reg_node( GSM_NET_SLEEP );
                        net_task_into_sleep_mode();
                    }
                }
                else if( net_send_st == SEND_NET_ERR )
                {
                    net_sleep_time = 0;
                    break;
                }
                else
                {
                    net_sleep_time = 0;
                }
            }
            /*******************************NET任务处于停止状态************************************/
            else if( net_power_st == TASK_STOP_MODE )
            {
                if( net_wait_net_close_suc() == pdPASS )
                {
                    net_close_reg_node( TASK_STOP_MODE );
                    if( net_task_into_stop_mode() ==  pdPASS )
                    {
                        gaoz_task_sleep(1000);
                        continue;
                    }
                }
                gaoz_task_sleep(1000);
            }
            /*******************************NET任务空循环状态************************************/
            else
            {
                gaoz_task_sleep(100);
            }
        }
    }
}

/** ****************************************************************************
* @remarks       static socket_status_e net_socket_state_detection( uint8_t index ,char *name,uint8_t *socket_id , uint8_t *buf, uint16_t *len)
* @brief         处理网络基层数据处理任务
* @param[in]     index网络节点数 
* @param[in]     *buf 接收网络数据的内存空间地址
* @param[out]    *socket_id 返回SOCKET ID数据
* @param[out]    *len 返回读取数据的长度
* @return        pdFAIL无数据 pdPASS有数据
* @attention     无
*******************************************************************************/
static socket_status_e net_socket_state_detection( uint8_t index ,char *name,uint8_t *socket_id , uint8_t *buf, uint16_t *len)
{
    uint8_t net_st = 0;
    socket_status_e st = SOCKET_ST_INIT;
    int ret = -1;
    struct timeval tv;
    fd_set readfds;    
    fd_set errorfds;
    /*检测socket创建的数量，当为0时直接退出*/
    if(( socket_bmt.socket_create_num == 0 ) || ( index >=  MAX_SOCKET_CONN_NUM ))
    {
        return st;
    }
    else
    {
        tv.tv_sec  = SOCKET_SELECT_TIME_S;
        /*select 等待的时间，最长时间等待SOCKET_SELECT_TIME_US，最多允许创建MAX_SOCKET_CONN_NUM个socket*/
        tv.tv_usec = 0;//SOCKET_SELECT_TIME_US;
    }
    net_module_run_state_get( MOD_STATE ,(uint8_t *)&net_st );
    /*检查网络接收数据包中的数据*/
    if(( socket_bmt.socket_handle_table[index].connStaus == 1 ) && ( net_st == MODULE_NET_OPEN ))
    {   
        FD_ZERO(&readfds);
        FD_ZERO(&errorfds); 
        FD_SET(socket_bmt.socket_handle_table[index].scoketId, &readfds);
        FD_SET(socket_bmt.socket_handle_table[index].scoketId, &errorfds);
        ret = fibo_sock_lwip_select( socket_bmt.socket_handle_table[index].scoketId + 1, &readfds, NULL, &errorfds, &tv );
        if( ret == 0 )
        {   
            st = SOCKET_SEL_OUT; /*等待超 时*/
        }
        else if( ret < 0 )   
        {
            st = SOCKET_SEL_ERR; /*网络异常*/
            log_debug_printf(DEBUG_MODE,name,"Socket select state anomaly,socket id=%d\r\n",socket_bmt.socket_handle_table[index].scoketId );
        }
        else 
        {   
            if( FD_ISSET( socket_bmt.socket_handle_table[index].scoketId, &errorfds ) ) 
            {
                st = SOCKET_NET_ERR; /*网络异常*/
                log_debug_printf(DEBUG_MODE,name,"Socket select state error,socket id=%d\r\n",socket_bmt.socket_handle_table[index].scoketId );
            }
            else if( FD_ISSET(socket_bmt.socket_handle_table[index].scoketId, &readfds ) ) 
            {           
                ret = fibo_sock_recv(socket_bmt.socket_handle_table[index].scoketId, (UINT8 *)buf, NET_RECV_DATA_LEN );      
                if( ret <= 0 )
                {
                    st = SOCKET_REV_ERR;
                    log_debug_printf(DEBUG_MODE,name,"Socket network state anomaly,socket id=%d\r\n",socket_bmt.socket_handle_table[index].scoketId );
                }
                else
                {   
                    *socket_id = socket_bmt.socket_handle_table[index].scoketId;
                    *len = ret;
                    st = SOCKET_REV_OK;
                    log_debug_printf(DEBUG_MODE,name,"Socket network receiving data,socket id=%d,data length=%d\r\n",socket_bmt.socket_handle_table[index].scoketId , ret);
                }
            }
        }
    }
    return st;
}

/** ****************************************************************************
* @remarks       static void net_rece_handle_task( void * pvParameters )
* @brief         接收网络底层数据
* @param[in]     * pvParameters 任务参数 
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
static void net_rece_handle_task( void * pvParameters )
{
    ( void )pvParameters;
    #define NET_ERR     ( 0x01 )
    uint8_t socket_id = 0 , index = 0;
    uint8_t net_st = 0;
    uint8_t *rev_buf = NULL;
    uint16_t rev_len = 0;
    char *task_name = NULL;
    socket_status_e socket_st = SOCKET_ST_INIT;
    socket_recv_para_t *recv_pv = NULL;
    recv_pv =  (socket_recv_para_t *)pvParameters;
    index = recv_pv->index;
    rev_buf = ( uint8_t * )recv_pv->buf;
    task_name = ( char * )recv_pv->name;
    mon_reg_task_dog( 60 * GAOZ_TICK_PERIOD_S ,(uint8_t * )task_name , TASK_SEM_NO );
    log_debug_send(DEBUG_MODE,task_name ,"Network socket handle task started successfully\r\n",0);
    for( ;; )
    {   
        mon_reset_task_dog();
        memset((uint8_t *)rev_buf ,0x00,NET_RECV_DATA_LEN );
                                                                              /*获取SOCKET ID SELECT 状态*/ 
        socket_st = net_socket_state_detection( index, task_name,&socket_id , (uint8_t *)rev_buf, &rev_len );
        if( socket_st == SOCKET_ST_INIT )                                     /* 当没有创建网络节点时直接对出操作*/
        {
            gaoz_task_sleep( SOCKET_SELECT_TIME_S );                          /*系统延时5ms*/
            net_st = NET_ERR;
        }
        else if( socket_st == SOCKET_REV_OK )                                 /*数据接收*/
        {
            net_printf_data_fun(NET_DATA_RECV,rev_buf,rev_len,socket_id);
            if( pdPASS == net_recv_data_funtion( index , ( uint8_t * )rev_buf , rev_len ))
            {
                //if( power_man_task_state_get( net_power_man_id ) == TASK_SLEEP_MODE )
                //{
                system_wakeup_queue_set( SYS_WAKEUP_TRIG_NET );           /*系统进入休眠后网络进行唤醒*/
                //}
                net_recv_status_fun( index , rev_len , NET_DATA_RECV_OK );    /*网络接收数据正确*/
            }
            else
            {
                net_recv_status_fun( index , rev_len , NET_DATA_RECV_ERROR ); /*网络接收数据异常*/
            }
        }
        else if( socket_st == SOCKET_NET_ERR )
        {   
            if( net_reg_state_check( index ) == pdPASS )                        /*当终端与网络断开时则链接断开，通知上层应用进行网络关闭*/
            {
                net_run_net_release();                                          /*将网络去激活*/
            }
            net_st = NET_ERR;                                                   /*网络异常退出*/
        }
        else if( socket_st == SOCKET_REV_ERR )                                  /*上层网络主动与设备断开*/
        {   
            net_link_state_check( index );                                      /*出现异常的网络节点，通知上层应用进行网络关闭*/
            net_st = NET_ERR;                                                   /*网络异常退出*/
        }
        else if( socket_st == SOCKET_SEL_ERR )
        {
            net_reg_state_check( index );
            net_st = NET_ERR;                                                   /*网络异常退出*/
        }
        /* 检测网络的状态，当检测到NET_ERR 时任务直接退出*/
        if( net_st == NET_ERR ) 
        {   
            index = 0;
            gaoz_fibo_free( ( void * )rev_buf );
            rev_buf = NULL;
            log_debug_send(INFOR_MODE,task_name ,"Network socket handle task exited successfully\r\n",0);
            task_name = NULL;
            mon_remove_task_dog();
            gaoz_thread_delete();
        }
    }
}
